﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SpiceNet.Diagnostics;
using SpiceNet.Circuits;

namespace SpiceNet.Simulations
{
    public class AcJob : Job
    {
        /// <summary>
        /// The starting frequency
        /// </summary>
        public double ACstartFreq = 0.0;

        /// <summary>
        /// The stopping frequency
        /// </summary>
        public double ACstopFreq = 0.0;

        /// <summary>
        /// The multiplier for decade/octave stepping
        /// Step for linear steps
        /// </summary>
        public double ACfreqDelta = 0.0;

        /// <summary>
        /// The frequency where we left off last time
        /// </summary>
        public double ACsaveFreq = 0.0;

        /// <summary>
        /// The type of steps that should be taken
        /// </summary>
        public AC.StepTypes ACstepType = AC.StepTypes.Linear;

        /// <summary>
        /// The number of steps in the simulation
        /// </summary>
        public int ACnumberSteps = 0;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name"></param>
        public AcJob(string name) : base(name) { }

        /// <summary>
        /// Constructor with logarithmic scaling (points per decade)
        /// </summary>
        /// <param name="name">The name of the AC job</param>
        /// <param name="numberSteps">The number of points per decade</param>
        /// <param name="startFreq">The starting frequency (Hz)</param>
        /// <param name="stopFreq">The stopping frequency (Hz)</param>
        public AcJob(string name, AC.StepTypes type, int numberSteps, double startFreq, double stopFreq)
            : base(name)
        {
            ACnumberSteps = numberSteps;
            ACstartFreq = startFreq;
            ACstopFreq = stopFreq;
            ACstepType = type;
        }

        /// <summary>
        /// Gets or sets the AC job parameters
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public override object this[string key]
        {
            get
            {
                switch (key)
                {
                    case "start": return ACstartFreq;
                    case "stop": return ACstopFreq;
                    case "numsteps": return ACnumberSteps;
                    default:
                        CircuitWarning.Warning(this, string.Format("Unrecognized parameter {0} for job {1}", key ?? "NULL", Name));
                        return null;
                }
            }
            set
            {
                switch (key)
                {
                    case "start":
                        ACstartFreq = Convert.ToDouble(value);
                        if (ACstartFreq <= 0.0)
                        {
                            ACstartFreq = 1.0;
                            throw new CircuitException("Frequency of 0.0 is invalid");
                        }
                        break;
                    case "stop":
                        ACstopFreq = Convert.ToDouble(value);
                        if (ACstopFreq <= 0.0)
                        {
                            ACstopFreq = 1.0;
                            throw new CircuitException("Frequency of 0.0 is invalid");
                        }
                        break;
                    case "numsteps": ACnumberSteps = Convert.ToInt32(value); break;
                    case "dec":
                        if (Convert.ToBoolean(value))
                            ACstepType = AC.StepTypes.Decade;
                        break;

                    case "oct":
                        if (Convert.ToBoolean(value))
                            ACstepType = AC.StepTypes.Octave;
                        break;

                    case "lin":
                        if (Convert.ToBoolean(value))
                            ACstepType = AC.StepTypes.Linear;
                        break;
                }
            }
        }
    }
}
